package com.ludomancy.hugealien;

import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;

public class SoulWorld
{
	private class SoulDistance implements Comparator
	{
		private Soul from;
		
		public SoulDistance(Soul from)
		{
			this.from = from;
		}
		
		public int compare(Object arg0, Object arg1)
		{
			Soul s1 = (Soul) arg0;
			Soul s2 = (Soul) arg1;
			float d1 = dist(s1, from);
			float d2 = dist(s2, from);
			return d1 < d2 ? -1 : d2 == d1 ? 0 : 1;
		}
	}
	
	public int timeCounter = 0;

	private Vector souls = new Vector();
	
	public boolean isThereAShockedSoul()
	{
		for (int i = 0; i < souls.size(); i++)
		{
			Soul other = (Soul) souls.elementAt(i);
			if(other.getMood() == Soul.MOOD_SHOCKED)
			{
				return true;
			}
		}
		return false;
	}
	
	public static SoulWorld generate(City city)
	{
		SoulWorld w = new SoulWorld();
		
		// create souls
		int nSouls = 11;
		for (int i = 0; i < nSouls; i++)
		{
			Soul s = new Soul();
			w.souls.add(s);
		}
		city.placeSouls(w.souls);
		
		// create love relationships between souls
		for (int i = 0; i < w.souls.size(); i++)
		{
			Soul me = (Soul) w.souls.elementAt(i);
			for (int j = i+1; j < w.souls.size(); j++)
			{
				Soul other = (Soul) w.souls.elementAt(j);
				// middle guy won't have relationships, so we force a change
				if(	other.canStartRelationship(me) && 
					i != nSouls/2 &&
					me.canStartRelationship(other) && 
					!areTooClose(me,other))
				{
					me.startRelationship(other, false);
					other.startRelationship(me, false);						
				}
			}
		}
		
//		// remove any possible initial suicides
//		for (int i = 0; i < w.souls.size();)
//		{
//			Soul me = (Soul) w.souls.elementAt(i);
//			if(me.relationships.isEmpty())
//			{
//				w.souls.removeElementAt(i);
//				Game.game.city.getUruguayan(me).remove();
//			}
//			else
//			{
//				i++;
//			}
//		}
		return w;
	}
	
	public Vector getCloseSouls(Soul s)
	{
		Vector others = (Vector) souls.clone();
		Collections.sort(others, new SoulDistance(s));
		return others;
	}
	
	public static float dist(Soul s1, Soul s2)
	{
		Uruguayan u1 = Game.game.city.getUruguayan(s1);
		Uruguayan u2 = Game.game.city.getUruguayan(s2);
		return Uruguayan.dist(u1, u2);
	}
	
	public static boolean areTooClose(Soul s1, Soul s2)
	{
		Uruguayan u1 = Game.game.city.getUruguayan(s1);
		Uruguayan u2 = Game.game.city.getUruguayan(s2);
		return Math.abs(u1.house.x - u2.house.x) <= 3 && Math.abs(u1.house.y - u2.house.y) <= 1;
	}
	
	public void cutRelationship(Soul s1, Soul s2)
	{
		s1.onRelationshipLost(s2);
		s2.onRelationshipLost(s1);
		timeCounter++;
	}
	
	public int deadones = 0;
	
	public void kill(Soul s)
	{
		souls.remove(s);
		deadones++;
		// affect other souls
		for (int i = 0; i < souls.size(); i++)
		{
			Soul other = (Soul) souls.elementAt(i);
			if(other.hasRelationship(s))
			{
				other.onDeath(s);
			}
		}
	}

	public boolean canCut(Soul soul, Soul soul2)
	{
		return soul.hasRelationship(soul2) && !soul.newRelationships.contains(soul2);
	}
}
